<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/paper-material/paper-material.html">
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../bower_components/paper-progress/paper-progress.html">
<link rel="import" href="../../bower_components/paper-styles/typography.html">
<link rel="import" href="../../bower_components/paper-listbox/paper-listbox.html">

<link rel="import" href="../app-form/app-form.html">
<script type="text/javascript" src="../volume-create-fields.js" inline></script>

<dom-module id="volume-create">
    <template>
        <style include="shared-styles forms single-page">
            #content {
                max-width: 900px;
            }

            paper-material {
                display: block;
                padding: 24px;
            }

            paper-progress {
                position: absolute;
                bottom: 85px;
                width: 100%;
                left: 0;
                right: 0;
            }

            :host>::slotted(paper-input-container) {
                padding-top: 16px;
                padding-bottom: 16px;
            }

            .dropdown-with-logos paper-item img {
                margin-right: 16px;
            }

            .single-head {
                @apply --volume-page-head-mixin
            }
        </style>
        <div id="content">
            <paper-material class="single-head layout horizontal">
                <span class="icon">
                    <iron-icon icon="[[section.icon]]"></iron-icon>
                </span>
                <div class="title flex">
                    <h2>
                        Create Volume
                    </h2>
                    <div class="subtitle">
                    </div>
                </div>
            </paper-material>
            <paper-material hidden$="[[hasCloudsWithVolumes]]">
                <p>Creating volumes is available in OpenStack, GCE, AWS, Azure ARM, Packet and Digital Ocean clouds
                    <br/> Add a cloud using the
                    <a href="/clouds/+add" class="blue-link regular">add cloud form</a>.
                </p>
            </paper-material>
            <paper-material hidden$=[[!hasCloudsWithVolumes]]>
                <div class="grid-row">
                    <paper-dropdown-menu class="dropdown-block l6 xs12 dropdown-with-logos" label="Select Cloud" horizontal-align="left">
                        <paper-listbox slot="dropdown-content" attr-for-selected="value" selected="{{selectedCloud::iron-select}}" class="dropdown-content">
                            <template is="dom-repeat" items="[[providers]]" as="provider">
                                <paper-item value="[[provider.id]]" disabled$="[[!_isOnline(provider.id, provider.state, model.clouds)]]">
                                    <img src="[[_computeProviderLogo(provider.provider)]]" width="24px">[[provider.title]]</paper-item>
                            </template>
                        </paper-listbox>
                    </paper-dropdown-menu>
                </div>
            </paper-material>
            <paper-material hidden$="[[selectedCloud]]">
                Depending on the cloud, different volume parameters may be required. Choose an available cloud for the corresponding
                    fields to appear.
            </paper-material>
            <template is="dom-if" if="[[selectedCloud]]" restamp>
                <paper-material>
                    <app-form id="volume_add" fields="{{fields}}" form="[[form]]" url="/api/v1/clouds/[[selectedCloud]]/volumes" on-response="_handleCreateVolumeResponse"
                        on-error="_handleError"></app-form>
                </paper-material>
            </template>
        </div>
        <iron-ajax id="getResourceGroups" contentType="application/json" handle-as="json" method="GET" on-request="_handleGetResourceGroupsRequest"
            on-response="_handleGetResourceGroupsResponse" on-error="_handleGetResourceGroupsError"></iron-ajax>

        <iron-ajax id="getLXDStoragePools" contentType="application/json" handle-as="json" method="GET" on-request="_handleGetLXDStoragePoolsRequest"
            on-response="_handleGetLXDStoragePoolsResponse" on-error="_handleGetLXDStoragePoolsError"></iron-ajax>
    </template>
    <script>
        Polymer({
            is: 'volume-create',

            properties: {
                section: {
                    type: Object
                },
                model: {
                    type: Object
                },
                providers: Array,
                form: {
                    type: Object,
                    value: function () {
                        return {}
                    }
                },
                fields: {
                    type: Array,
                    value: function () { return [] }
                },
                volumesFields: {
                    type: Array,
                    value: function () {
                        return VOLUME_CREATE_FIELDS;
                    }
                },
                hasCloudsWithVolumes: {
                    type: Boolean,
                    value: false
                },
                selectedCloud: {
                    type: String,
                    value: false
                },
                resourceGroupsFieldIndex: {
                    type: Number
                },
                lxdStoragePoolsFieldIndex: {
                    type: Number
                }
            },
            observers: [
                '_cloudsChanged(model.clouds.*)',
                '_cloudChanged(selectedCloud)',
                '_locationChanged(fields.1.value)',
                '_diskCategoryChanged(fields.3.value)',
                '_fieldValuesChanged(fields.*)'
            ],
            _cloudsChanged: function (clouds) {
                var volumeClouds = this.model && this.model.cloudsArray.filter(function (cloud) {
                    return VOLUME_CREATE_FIELDS.map(i => i.provider).indexOf(cloud.provider) > -1;
                });
                this.set('providers', volumeClouds);
                this.set('hasCloudsWithVolumes', volumeClouds && volumeClouds.length > 0 ? true : false);
            },
            _computeProviderLogo: function (className) {
                var identifier = className.replace('_', '');
                return 'assets/providers/provider-' + identifier + '.png';
            },
            _isOnline: function (cloud, state, clouds) {
                return this.model.clouds[cloud] && this.model.clouds[cloud].state == 'online';
            },
            _cloudChanged: function (selectedCloud) {
                // clear to reset
                this.set('fields', []);
                var volumeFields = [];
                if (this.selectedCloud) {
                    var provider = this.model.clouds[selectedCloud].provider;
                    volumeFields = this.volumesFields.find(function (c) {
                        return c.provider == provider;
                    });
                }
                // add cloud fields
                if (volumeFields.fields)
                    this.set('fields', JSON.parse(JSON.stringify(volumeFields.fields.filter(function(f){
                        return !f.onForm || f.onForm == 'volume_add ';
                    }))));

                // set values by provider
                this._updateFields(selectedCloud);
            },
            _updateFields: function(selectedCloud) {
                if (this.model && this.model.clouds && this.selectedCloud && this.model.clouds[this
                        .selectedCloud]) {
                    var cloudId = this.selectedCloud;
                    // if is azure arm, change required values
                    if (this.model.clouds[cloudId].provider == "azure_arm") {
                        this._updateResourceGroups(cloudId);
                    }

                    if(this.model.clouds[cloudId].provider == "lxd"){
                        this._updateLXDStoragePools(cloudId);
                    }

                    this.fields.forEach(function (f, index) {
                        if (f.name.endsWith("location")) {
                            var locations = this.model.clouds[cloudId].locationsArray.slice();
                            if (locations.length == 1 && locations[0].name == '') {
                                // If there's a single location preselect it and hide the field
                                f.value = locations[0].id;
                                f.show = false;
                                locations = [];
                            }
                            if (this.model.clouds[cloudId].provider == 'packet') {
                                locations = locations.filter(function(l) {
                                    if (l.extra.features.indexOf('storage') > -1) {
                                        return true;
                                    }
                                });
                            } else if (this.model.clouds[cloudId].provider == 'aliyun_ecs') {
                                locations = locations.filter(function(l) {
                                    if (l.extra.available_disk_categories.length) {
                                        return true;
                                    }
                                });
                            }
                            f.options = locations;
                        }
                    }.bind(this));
                }
            },
            _locationChanged: function (locationId, what) {
                if (!locationId || !this.selectedCloud || !this.model.clouds[this.selectedCloud]) return;
                var provider = this.model.clouds[this.selectedCloud].provider,
                    location = this.model.clouds[this.selectedCloud].locations[locationId];
                if (provider == 'aliyun_ecs') {
                    var diskCategoryOptions = this.volumesFields.find(function (cloud) {
                        return cloud.provider == provider;
                    }).fields[3].options.filter(function(option) {
                        return location.extra.available_disk_categories.indexOf(option.val) > -1;
                    });
                    this.set('fields.3.options', diskCategoryOptions);
                }
            },
            _diskCategoryChanged: function(diskCategory) {
                if (!diskCategory || !this.selectedCloud || !this.model.clouds[this.selectedCloud]) return;
                var provider = this.model.clouds[this.selectedCloud].provider, minSize = 1;
                if (provider == 'aliyun_ecs') {
                    if (diskCategory != 'cloud') {
                        minSize = 20;
                    } else {
                        minSize = 5;
                    }
                    this.set('fields.2.min', minSize);
                    if (Number(this.fields[2].value) < minSize) {
                        this.set('fields.2.value', minSize);
                    }
                    this.set('fields.2.helptext', 'A minimum of '+ minSize + ' GB is required.')
                }
            },
            _fieldValuesChanged: function(changeRecord) {
                var fieldName = this.get(changeRecord.path.replace('.value', '')).name;
                if (['create_resource_group','ex_resource_group','new_resource_group']
                    .indexOf(fieldName) > -1) {
                    this._updateResourceGroupValue(this.selectedCloud);
                }
            },
            _updateResourceGroupValue: function(cloudId) {
                var createFieldIndex = this._fieldIndexByName('create_resource_group');
                var existingFieldIndex = this._fieldIndexByName('ex_resource_group');
                var newFieldIndex = this._fieldIndexByName('new_resource_group');
                var resourceGroupFieldIndex = this._fieldIndexByName('resource_group');

                if (this.get('fields.'+ createFieldIndex +'.value') == true ) {
                    this.set('fields.'+ resourceGroupFieldIndex +'.value', this.get('fields.'+ newFieldIndex +'.value'))
                } else {
                    this.set('fields.'+ resourceGroupFieldIndex +'.value', this.get('fields.'+ existingFieldIndex +'.value'))
                }
            },
            _updateResourceGroups: function(cloudId) {
                var fieldIndex = this._fieldIndexByName('ex_resource_group');
                if (fieldIndex && this.get('fields.' + fieldIndex + '.options') && !this.get('fields.' + fieldIndex + '.options').length) {
                    this._getResourceGroups(cloudId, fieldIndex);
                }
            },
            _getResourceGroups: function(cloudId, index) {
                this.set("resourceGroupsFieldIndex",index);
                this.$.getResourceGroups.headers["Content-Type"] = 'application/json';
                this.$.getResourceGroups.headers["Csrf-Token"] = CSRF_TOKEN;
                this.$.getResourceGroups.url = '/api/v1/clouds/'+ cloudId +'/resource-groups';
                this.$.getResourceGroups.generateRequest();
            },
            _handleGetResourceGroupsRequest: function(e) {
                this.set('fields.' + this.resourceGroupsFieldIndex + '.loader', true);
            },
            _handleGetResourceGroupsResponse: function(e) {
                this.set('fields.' + this.resourceGroupsFieldIndex + '.options', e.detail.response || []);
                this.shadowRoot.querySelector('app-form').dispatchEvent(new CustomEvent('fields-changed', {detail: {file: 'volume-create.html'}}));
                this.set('fields.' + this.resourceGroupsFieldIndex + '.loader', false);
            },
            _handleGetResourceGroupsError: function(e) {
                console.error('Got resource groups error', e);
            },
            _updateLXDStoragePools: function(cloudId) {
                var fieldIndex = this._fieldIndexByName('pool_id');
                if (fieldIndex && this.get('fields.' + fieldIndex + '.options') && !this.get('fields.' + fieldIndex + '.options').length) {
                    this._getLXDStoragePools(cloudId, fieldIndex);
                }
            },
            _getLXDStoragePools: function(cloudId, index) {
                this.set("lxdStoragePoolsFieldIndex",index);
                this.$.getLXDStoragePools.headers["Content-Type"] = 'application/json';
                this.$.getLXDStoragePools.headers["Csrf-Token"] = CSRF_TOKEN;
                this.$.getLXDStoragePools.url = '/api/v1/clouds/'+ cloudId +'/storage-pools';
                this.$.getLXDStoragePools.generateRequest();
            },
            _handleGetLXDStoragePoolsRequest: function(e) {
                this.set('fields.' + this.lxdStoragePoolsFieldIndex + '.loader', true);
            },
            _handleGetLXDStoragePoolsResponse: function(e) {
                this.set('fields.' + this.lxdStoragePoolsFieldIndex + '.options', e.detail.response || []);
                this.shadowRoot.querySelector('app-form').dispatchEvent(new CustomEvent('fields-changed', {detail: {file: 'volume-create.html'}}));
                this.set('fields.' + this.lxdStoragePoolsFieldIndex + '.loader', false);
            },
            _handleGetLXDStoragePoolsError: function(e) {
                console.error('Got LXD storage pools error error', e);
            },
            _fieldIndexByName: function (name) {
                var field = this.fields.findIndex(function (f) {
                    return f.name == name;
                });
                return field;
            },
            _handleCreateVolumeResponse: function (e) {
                var response = JSON.parse(e.detail.xhr.response);
                this.dispatchEvent(new CustomEvent('go-to', {
                    bubbles: true, composed: true,
                    detail: {
                        url: '/volumes'
                    }}));
            },
            _handleError: function (e) {
                console.log(e);
                this.$.errormsg.textContent = e.detail.request.xhr.responseText;
                this.set('formError', true);
            },
            _goBack: function () {
                history.back();
            }
        });
    </script>
</dom-module>